#ifndef MUTEX_H_
#define MUTEX_H_

#include <pthread.h>

namespace TP { namespace Threading { 

    class Mutex {
private:
	pthread_mutex_t _mutex;
	pthread_cond_t _condVar;

public:
	// Crea un mutex con atributos por default
	Mutex() {
		pthread_mutex_init(&_mutex, 0);
		pthread_cond_init(&_condVar, 0);
	}

	// Lock
	void lock() {
		pthread_mutex_lock(&_mutex);
	}

	// Unlock
	void unlock() {
		pthread_mutex_unlock(&_mutex);
	}

	// signal
	void signal() {
		pthread_cond_signal(&_condVar);
	}

	// wait
	void wait() {
		pthread_cond_wait(&_condVar, &_mutex);
	}

	// Destructor
	virtual ~Mutex() {
		pthread_mutex_destroy(&_mutex);
		pthread_cond_destroy(&_condVar);
	}

	friend class Lock;
};

// Patrón RAII para la clase mutex
class Lock {
private:
	Mutex &_mutex;

public:
	// Construye un Lock bloqueando el mutex
	explicit Lock(Mutex &mutex) : _mutex(mutex) {_mutex.lock();}

	// Destruye el Lock desbloqueando el mutex
	~Lock() {_mutex.unlock();}
};

}}

#endif /* MUTEX_H_ */
